package org.example.easybuy.interceptor;

import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import org.example.easybuy.annotation.PermissionCheck;
import org.example.easybuy.dao.UserDao;
import org.example.easybuy.entity.User;
import org.example.easybuy.exceptions.TokenNotCorrectException;
import org.example.easybuy.service.UserService;
import org.example.easybuy.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Component
public class MyInterceptor implements HandlerInterceptor {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserDao userDao;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //前端传过来的token
        String authorization=request.getHeader("Authorization");
        System.out.println("==============="+authorization);
        if(authorization==null)
        {
            //未登录
            throw new TokenNotCorrectException("no-token");
        }

        String loginName="";
        try{
            loginName = JwtUtil.getLoginName(authorization);
        }catch(SignatureVerificationException s)  //签名验证失败异常
        {
            //验证签名失败
            throw new TokenNotCorrectException("sign-error");
        }catch(TokenExpiredException t)     //token过期异常
        {
            //token失效
            throw new TokenNotCorrectException("token-expired");    //需要重新登录
        }
        String token="";
        if(stringRedisTemplate.hasKey(loginName))
        {
            token=stringRedisTemplate.opsForValue().get(loginName);
        }
        if(!token.equals(authorization)|| token=="")
        {
            //redis中的token不等于接收到的token，验证失败
            throw new TokenNotCorrectException("inCorrect");
        }

        //toke延期
        Date exp = JwtUtil.getExpires(token);
        if(exp.getTime() - System.currentTimeMillis() <= 2 * 60 * 1000 ) {
            //进行token置换
            String newToken = JwtUtil.createToken(loginName);
            stringRedisTemplate.opsForValue().set(loginName, newToken, 30, TimeUnit.MINUTES);
            response.setHeader("Access-Control-Expose-Headers", "x-token");
            response.setHeader("x-token", newToken);
        }

        boolean isHandlerMethod = handler instanceof HandlerMethod;
        if (!isHandlerMethod) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        PermissionCheck checkPermission = handlerMethod.getMethodAnnotation(PermissionCheck.class);
        if(checkPermission == null) {
//			throw new RuntimeException("无权限");
            return true;
        }
        String[] roles =  checkPermission.value();
        if(checkRole(loginName, roles)) {
            return true;
        }else {
            throw new TokenNotCorrectException("no-permission");
        }
    }

    public boolean checkRole(String loginName,String[] roles)
    {
        User user=userDao.selectUserByLoginName(loginName);
        for(String role:roles)
        {
            if(role.equals(user.getType().toString()))
            {
                return true;
            }
        }
        return false;
    }
}
